package com.itic.appbase.applications.exports.ExportExcelWithZip;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ZipUtils { 
    
    private static final Logger log = LoggerFactory.getLogger(ZipUtils.class); 
           
    private ZipUtils(){
        
    }
    
   /**
     * 创建ZIP文件
     * @param sourcePath 文件或文件夹路径
     * @param zipPath 生成的zip文件存在路径（包括文件名）
     */ 
    public static void zip(String sourcePath, String zipPath) { 
        FileOutputStream fos = null; 
        ZipOutputStream zos = null; 
        try { 
            fos = new FileOutputStream(zipPath); 
            zos = new ZipOutputStream(fos); 
            writeZip(new File(sourcePath), "", zos); 
        } catch (Exception e) { 
            log.error("创建ZIP文件失败",e); 
        } finally { 
            try { 
                if (zos != null) { 
                    zos.flush();
                    zos.close(); 
                }
                if(fos!=null){
                    fos.flush();
                    fos.close();
                }
            } catch (IOException e) { 
                log.error("创建ZIP文件失败",e); 
            } 
   
        } 
    } 
    
    @SuppressWarnings("rawtypes")
    public static void unZip(String sourcePath, String targetPath) throws IOException {
        
            BufferedInputStream bi;  
      
            ZipFile zf = new ZipFile(sourcePath, "GBK");//支持中文   
      
            Enumeration e = zf.getEntries();  
            while (e.hasMoreElements()) {  
                ZipEntry ze2 = (ZipEntry) e.nextElement();  
                String entryName = ze2.getName();  
                String path = targetPath + "/" + entryName;  
                if (ze2.isDirectory()) {  
                    //System.out.println("正在创建解压目录 - " + entryName);  
                    File decompressDirFile = new File(path);  
                    if (!decompressDirFile.exists()) {  
                        decompressDirFile.mkdirs();  
                    }  
                } else {  
                    //System.out.println("正在创建解压文件 - " + entryName);  
                    String fileDir = path.substring(0, path.lastIndexOf("/"));  
                    File fileDirFile = new File(fileDir);  
                    if (!fileDirFile.exists()) {  
                        fileDirFile.mkdirs();  
                    }  
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(  
                            targetPath + "/" + entryName));  
      
                    bi = new BufferedInputStream(zf.getInputStream(ze2));  
                    byte[] readContent = new byte[1024];  
                    int readCount = bi.read(readContent);  
                    while (readCount != -1) {  
                        bos.write(readContent, 0, readCount);  
                        readCount = bi.read(readContent);  
                    }  
                    bos.close();  
                }  
            }  
            zf.close();  
      
    }
    
    private static void writeZip(File file, String parentPath, ZipOutputStream zos) { 
        if(file.exists()){ 
            //处理文件夹 
            if(file.isDirectory()){ 
                parentPath+=file.getName()+File.separator; 
                File [] files=file.listFiles(); 
                for(File f:files){ 
                    writeZip(f, parentPath, zos);
                } 
            }else{ 
                FileInputStream fis=null; 
                DataInputStream dis=null; 
                try { 
                    fis=new FileInputStream(file); 
                    dis=new DataInputStream(new BufferedInputStream(fis)); 
                    ZipEntry ze = new ZipEntry(parentPath + file.getName()); 
                    zos.putNextEntry(ze); 
                    //添加编码，如果不添加，当文件以中文命名的情况下，会出现乱码 
                    // ZipOutputStream的包一定是apache的ant.jar包。JDK也提供了打压缩包，但是不能设置编码 
                    zos.setEncoding("GBK"); 
                    byte [] content=new byte[1024]; 
                    int len; 
                    while((len=fis.read(content))!=-1){ 
                        zos.write(content,0,len); 
                    } 
                    zos.flush();
                    zos.closeEntry();
                } catch (FileNotFoundException e) { 
                    log.error("创建ZIP文件失败",e); 
                } catch (IOException e) { 
                    log.error("创建ZIP文件失败",e); 
                }finally{ 
                    try { 
                        if(dis!=null){ 
                            dis.close(); 
                        } 
                        if(fis!=null){
                            fis.close();
                        }
                    }catch(IOException e){ 
                        log.error("创建ZIP文件失败",e); 
                    } 
                } 
            } 
        } 
    }     
    public static void main(String[] args) { 
        //测试把F盘下的所有文件打包压缩成sql.zip文件放在F盘根目录下 
        //ZipUtils.zip("D:/logs", "D:/logs.zip");
        try {
            ZipUtils.unZip("D:/logs.zip", "d:/logs2");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    } 
}